package utils

import (
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"strconv"
	"time"
)

type TokenClaims struct {
	UserId  string `json:"user_id"`
	AppId   string `json:"app_id"`
	UnionId string `json:"union_id"` //todo 为了兼容PHP接口暂时设置成string
	jwt.StandardClaims
}

const TokenSecret = "meetingTokenSecret"
const TokenExpire = "24"

// ParseToken  token解析
func ParseToken(tokenString string) (*TokenClaims, error) {
	token, err := jwt.ParseWithClaims(tokenString, &TokenClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(TokenSecret), nil
	})
	if err != nil {
		return nil, err
	}
	if claims, ok := token.Claims.(*TokenClaims); ok && token.Valid {
		return claims, nil
	}
	return nil, nil
}

func CheckToken(tokenString string) jwt.MapClaims {
	token, _ := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
		if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
			return nil, fmt.Errorf("Unexpected signing method")
		}
		return []byte("TokenSecrets"), nil
	})
	if token == nil {
		return nil
	}
	claims, _ := token.Claims.(jwt.MapClaims)

	return claims
}

// 生成 token
func MakeToken(userId string, unionid string, appid string) (string, error) {
	exp, err := strconv.Atoi(TokenExpire)
	if err != nil {
		return "", err
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, TokenClaims{
		UserId:  userId,
		AppId:   appid,
		UnionId: unionid,
		StandardClaims: jwt.StandardClaims{
			ExpiresAt: time.Now().Add(time.Hour * time.Duration(exp)).Unix(),
		},
	})

	tokenString, err := token.SignedString([]byte(TokenSecret))
	return tokenString, err
}
